package com.gitee.xjt2016.modules.common.utils;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * ListUtils.
 *
 * @author xiongjinteng@raycloud.com
 */
public class ListUtils {

    /**
     * 大集合分隔分批处理
     *
     * @param list     list
     * @param pageSize pageSize
     * @param <T>      <T>
     * @return <T>
     */
    public static <T> List<List<T>> split2List(List<T> list, int pageSize) {
        if (list == null || list.size() <= 0) return null;

        if (pageSize <= 0) {
            throw new IllegalArgumentException("分隔大小不能小于或等于0");
        }
        List<List<T>> listArray = new ArrayList<>();
        List<T> subList = null;
        for (int i = 0; i < list.size(); i++) {
            if (i % pageSize == 0) {//每次到达页大小的边界就重新申请一个subList
                subList = new ArrayList<>();
                listArray.add(subList);
            }
            subList.add(list.get(i));
        }
        return listArray;
    }

    /**
     * 将一个list均分成n个list,主要通过偏移量来实现的
     *
     * @param source source
     * @return <T>
     */
    public static <T> List<List<T>> averageAssign(List<T> source, int n) {
        if (source == null || source.size() <= 0) return null;
        List<List<T>> result = new ArrayList<>();
        int remaider = source.size() % n;  //(先计算出余数)
        int number = source.size() / n;  //然后是商
        int offset = 0;//偏移量
        for (int i = 0; i < n; i++) {
            List<T> value = new ArrayList<>();
            if (remaider > 0) {
                value = source.subList(i * number + offset, (i + 1) * number + offset + 1);
                remaider--;
                offset++;
            } else {
                value = source.subList(i * number + offset, (i + 1) * number + offset);
            }
            result.add(value);
        }
        return result;
    }

    /**
     * transfer list into map
     *
     * @param list          list
     * @param fieldName4Key fieldName4Key
     * @return map
     */
    public static <K, V> Map<K, V> list2MapByFieldName(List<V> list, String fieldName4Key, Class<V> c) {
        Map<K, V> map = new HashMap<>();
        if (list != null) {
            try {
                PropertyDescriptor propDesc = new PropertyDescriptor(fieldName4Key, c);
                Method methodGetKey = propDesc.getReadMethod();
                for (V value : list) {
                    @SuppressWarnings("unchecked")
                    K key = (K) methodGetKey.invoke(value);
                    if (!map.containsKey(key)) {
                        map.put(key, value);
                    }
                }
            } catch (Exception e) {
                throw new IllegalArgumentException("field can't match the key!");
            }
        }
        return map;
    }

    /**
     * 获取集合中对象中的某个字段,不为空
     *
     * @param list          list
     * @param fieldName4Key fieldName4Key
     * @param clazz         clazz
     * @param <T>           <T>
     * @param <E>           <E>
     * @return List
     */
    public static <T, E> List<E> getElementList(List<T> list, String fieldName4Key, Class<T> clazz) {
        List<E> elementList = new ArrayList<>();
        if (list != null) {
            try {
                PropertyDescriptor propDesc = new PropertyDescriptor(fieldName4Key, clazz);
                Method methodGetKey = propDesc.getReadMethod();
                for (T value : list) {
                    @SuppressWarnings("unchecked")
                    E key = (E) methodGetKey.invoke(value);
                    if (key != null) {
                        elementList.add(key);
                    }
                }
            } catch (Exception e) {
                throw new IllegalArgumentException("field can't match the key!");
            }
        }
        return elementList;
    }

    public static void main(String[] s) {
        List<String> strList = new ArrayList<>();
        for (int i = 0; i < 120; i++) {
            strList.add("aa" + (i + 1));
        }
        List<List<String>> list = split2List(strList, 200);

        int index = 1;
        for (List<String> strList2 : list) {
            System.out.println(index++);
            System.out.println("----------------------------------");
            for (String str : strList2) {
                System.out.print(str + "\t");
            }
            System.out.println("END");
            System.out.println();
        }
    }
}
